import * as vscode from 'vscode';
import { DeviceConnectionManager } from './deviceConnectionManager';
import { RawREPLManager } from './rawReplManager';
import * as path from 'path';
import * as fs from 'fs';

export interface DeviceFile {
    name: string;
    path: string;
    isDirectory: boolean;
    size?: number;
}

export class DeviceFileManager {
    private connectionManager: DeviceConnectionManager;
    private rawReplManager: RawREPLManager;

    constructor(connectionManager: DeviceConnectionManager) {
        this.connectionManager = connectionManager;
        this.rawReplManager = new RawREPLManager(connectionManager);
    }

    public async listFiles(remotePath: string = '/'): Promise<DeviceFile[]> {
        if (!this.connectionManager.isConnected) {
            throw new Error('Device not connected');
        }

        console.log(`Listing files in ${remotePath} using Raw REPL...`);

        // 使用 Raw REPL 列出文件
        try {
            await this.rawReplManager.enterRawREPL();

            const code = `
import os
files = os.listdir('${remotePath}')
for f in files:
    try:
        full_path = '${remotePath}/' + f if '${remotePath}' != '/' else '/' + f
        stat = os.stat(full_path)
        is_dir = (stat[0] & 0x4000) != 0
        size = stat[6] if not is_dir else 0
        print(f + '|' + str(is_dir) + '|' + str(size))
    except:
        print(f + '|False|0')
`;

            const [stdout, stderr] = await this.rawReplManager.execute(code);

            // 检查错误
            if (stderr && stderr.trim().length > 0) {
                throw new Error(`List files failed: ${stderr.trim()}`);
            }

            // 解析文件列表
            const files: DeviceFile[] = [];
            const lines = stdout.split('\n');

            for (const line of lines) {
                if (!line.trim()) {
                    continue;
                }

                // 解析文件信息：name|isDirectory|size
                const parts = line.trim().split('|');
                if (parts.length === 3) {
                    files.push({
                        name: parts[0],
                        path: path.posix.join(remotePath, parts[0]),
                        isDirectory: parts[1] === 'True',
                        size: parseInt(parts[2]) || 0
                    });
                }
            }

            console.log(`Found ${files.length} files/directories`);
            return files;
        } finally {
            await this.rawReplManager.exitRawREPL();
        }
    }    public async uploadFile(localPath: string, remotePath: string): Promise<void> {
        if (!this.connectionManager.isConnected) {
            throw new Error('Device not connected');
        }

        if (!fs.existsSync(localPath)) {
            throw new Error(`Local file not found: ${localPath}`);
        }

        const fileContent = fs.readFileSync(localPath, 'utf8');
        console.log(`Uploading file to ${remotePath} using Raw REPL...`);

        // 使用 Raw REPL 上传文件
        try {
            await this.rawReplManager.enterRawREPL();

            // 构建文件写入代码
            const code = `
with open('${remotePath}', 'w') as f:
    f.write(${JSON.stringify(fileContent)})
`;

            // 执行代码
            const [stdout, stderr] = await this.rawReplManager.execute(code);

            // 检查错误
            if (stderr && stderr.trim().length > 0) {
                throw new Error(`Upload failed: ${stderr.trim()}`);
            }

            console.log('File uploaded successfully');
        } finally {
            await this.rawReplManager.exitRawREPL();
        }
    }    public async downloadFile(remotePath: string, localPath: string): Promise<void> {
        if (!this.connectionManager.isConnected) {
            throw new Error('Device not connected');
        }

        console.log(`Downloading file from ${remotePath} using Raw REPL...`);

        // 使用 Raw REPL 下载文件
        try {
            await this.rawReplManager.enterRawREPL();

            // 读取文件内容
            const code = `
with open('${remotePath}', 'r') as f:
    print(f.read(), end='')
`;

            const [stdout, stderr] = await this.rawReplManager.execute(code);

            // 检查错误
            if (stderr && stderr.trim().length > 0) {
                throw new Error(`Download failed: ${stderr.trim()}`);
            }

            // 保存文件内容
            fs.writeFileSync(localPath, stdout);
            console.log('File downloaded successfully');
        } finally {
            await this.rawReplManager.exitRawREPL();
        }
    }

    public async runFileInRAM(fileContent: string): Promise<void> {
        if (!this.connectionManager.isConnected) {
            throw new Error('Device not connected');
        }

        console.log(`Executing code in RAM using Raw REPL...`);

        // 使用 Raw REPL 执行代码
        try {
            await this.rawReplManager.enterRawREPL();

            // 直接执行代码
            const [stdout, stderr] = await this.rawReplManager.execute(fileContent);

            // 检查错误
            if (stderr && stderr.trim().length > 0) {
                throw new Error(`Execution failed:\n${stderr.trim()}`);
            }

            // 如果有标准输出，显示给用户
            if (stdout && stdout.trim().length > 0) {
                console.log('Program output:', stdout);
            }

            console.log('Code executed successfully');
        } finally {
            await this.rawReplManager.exitRawREPL();
        }
    }    public async runFile(remotePath: string): Promise<void> {
        if (!this.connectionManager.isConnected) {
            throw new Error('Device not connected');
        }

        const command = `
try:
    exec(open('${remotePath}').read())
    print('\\nRUN_COMPLETE')
except Exception as e:
    print('RUN_ERROR:', str(e))
`;

        console.log(`Running file: ${remotePath}`);
        await this.connectionManager.sendCommand(command);
    }

    public async deleteFile(remotePath: string): Promise<void> {
        if (!this.connectionManager.isConnected) {
            throw new Error('Device not connected');
        }

        console.log(`Deleting file ${remotePath} using Raw REPL...`);

        // 使用 Raw REPL 删除文件
        try {
            await this.rawReplManager.enterRawREPL();

            const code = `
import os
os.remove('${remotePath}')
`;

            const [stdout, stderr] = await this.rawReplManager.execute(code);

            // 检查错误
            if (stderr && stderr.trim().length > 0) {
                throw new Error(`Delete failed: ${stderr.trim()}`);
            }

            console.log('File deleted successfully');
        } finally {
            await this.rawReplManager.exitRawREPL();
        }
    }

    public async createDirectory(remotePath: string): Promise<void> {
        if (!this.connectionManager.isConnected) {
            throw new Error('Device not connected');
        }

        console.log(`Creating directory ${remotePath} using Raw REPL...`);

        // 使用 Raw REPL 创建目录
        try {
            await this.rawReplManager.enterRawREPL();

            const code = `
import os
os.mkdir('${remotePath}')
`;

            const [stdout, stderr] = await this.rawReplManager.execute(code);

            // 检查错误
            if (stderr && stderr.trim().length > 0) {
                throw new Error(`Directory creation failed: ${stderr.trim()}`);
            }

            console.log('Directory created successfully');
        } finally {
            await this.rawReplManager.exitRawREPL();
        }
    }
}
